//
//  TPPermissionNotificationTools.m
//  Pods
//
//  Created by caixun on 16/1/22.
//
//


#import "MPTAuthorizationNotificationTools.h"


#define MPTDeviceToken @"MPTDeviceToken"
#define MPTAskedForNotificationPermission @"MPTAskedForNotificationPermission"


@interface MPTAuthorizationNotificationTools ()
{
    NotificationAuthorizationHandler _completion;
}


@end


@implementation MPTAuthorizationNotificationTools


+ (instancetype)sharedInstance
{
    static MPTAuthorizationNotificationTools *_instance = nil;
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^{
        _instance = [[MPTAuthorizationNotificationTools alloc] init];
    });
    
    return _instance;
}

- (MPE_AuthorizationStatus)authorizationStatus
{
    BOOL notificationsOn = NO;
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(currentUserNotificationSettings)])
    {
        notificationsOn = ([[UIApplication sharedApplication] currentUserNotificationSettings].types != UIUserNotificationTypeNone);
    }
    else
    {
        notificationsOn = ([[UIApplication sharedApplication] enabledRemoteNotificationTypes] != UIRemoteNotificationTypeNone);
    }
    if (notificationsOn)
    {
        return MPE_AuthorizationAuthorized;
    }
    else
    {
        BOOL previouslyAsked = [[NSUserDefaults standardUserDefaults] boolForKey:MPTAskedForNotificationPermission];
        NSString *token = [[NSUserDefaults standardUserDefaults] objectForKey:MPTDeviceToken];
        if (token)
        {
            return MPE_AuthorizationAuthorized;
        }
        else if (previouslyAsked)
        {
            return MPE_AuthorizationDenied;
        }
        else
        {
            return MPE_AuthorizationNotDetermined;
        }
    }
}

- (void)authorize:(NotificationAuthorizationHandler)completion
{
    bool previouslyAsked = [[NSUserDefaults standardUserDefaults] boolForKey:MPTAskedForNotificationPermission];
    
    BOOL notificationsOn = NO;
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(currentUserNotificationSettings)])
    {
        notificationsOn = ([[UIApplication sharedApplication] currentUserNotificationSettings].types !=
                           UIUserNotificationTypeNone);
    }
    else
    {
        notificationsOn = ([[UIApplication sharedApplication] enabledRemoteNotificationTypes] !=
                           UIRemoteNotificationTypeNone);
    }
    if (notificationsOn)
    {
        _completion = completion;
        [self actuallyAuthorize];
    }
    else if (!previouslyAsked)
    {
        _completion = completion;
        [self actuallyAuthorize];
    }
    else
    {
        if (completion)
        {
            completion(nil, nil);
        }
    }
}

- (void)unauthorize
{
    [[UIApplication sharedApplication] unregisterForRemoteNotifications];
    [[NSUserDefaults standardUserDefaults] setObject:nil forKey:MPTDeviceToken];
    [[NSUserDefaults standardUserDefaults] setBool:false forKey:MPTAskedForNotificationPermission];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

- (void)notificationResult:(NSData *)deviceToken error:(NSError *)error
{
    if (deviceToken)
    {
        NSString *deviceID = [self parseDeviceID:deviceToken];
        
        [[NSUserDefaults standardUserDefaults] setObject:deviceID forKey:MPTDeviceToken];
        [[NSUserDefaults standardUserDefaults] synchronize];
        
        if (_completion)
        {
            _completion(deviceID, nil);
        }
    }
    else
    {
        if (_completion)
        {
            _completion(nil, error);
        }
    }
}

- (NSString *)deviceID
{
    return [[NSUserDefaults standardUserDefaults] objectForKey:MPTDeviceToken];
}

- (MPE_AuthorizationType)permissionType
{
    return MPE_AuthorizationNotification;
}

- (void)actuallyAuthorize
{
    [[NSUserDefaults standardUserDefaults] setBool:true forKey:MPTAskedForNotificationPermission];
    [[NSUserDefaults standardUserDefaults] synchronize];
    
    if ([[UIApplication sharedApplication]
         respondsToSelector:@selector(registerUserNotificationSettings:)])
    {
        UIUserNotificationSettings *userNotificationSettings = self.userNotificationSettings;
        if (!userNotificationSettings)
        {
            userNotificationSettings = [UIUserNotificationSettings
                                        settingsForTypes:(UIUserNotificationTypeAlert | UIUserNotificationTypeBadge |
                                                          UIUserNotificationTypeSound)
                                        categories:nil];
        }
        [[UIApplication sharedApplication] registerUserNotificationSettings:userNotificationSettings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
    else
    {
        UIRemoteNotificationType remoteNotificationType = self.remoteNotificationType;
        if (!remoteNotificationType)
        {
            remoteNotificationType = (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge |
                                      UIRemoteNotificationTypeSound);
        }
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:remoteNotificationType];
    }
}

#pragma mark - Helpers

- (NSString *)parseDeviceID:(NSData *)deviceToken
{
    NSString *token = [deviceToken description];
    return [[self regex] stringByReplacingMatchesInString:token
                                                  options:0
                                                    range:NSMakeRange(0, [token length])
                                             withTemplate:@""];
}

- (NSRegularExpression *)regex
{
    NSError *error;
    NSRegularExpression *exp =
    [NSRegularExpression regularExpressionWithPattern:@"[<> ]"
                                              options:NSRegularExpressionCaseInsensitive
                                                error:&error];
    
    if (!exp)
    {
        NSLog(@"Failed to instantiate the regex parser due to %@", error);
    }
    
    return exp;
}


@end
